package com.nervenets.web.controller.statistics;

import com.nervenets.utils.JodaUtils;
import com.nervenets.web.controller.BaseController;
import com.nervenets.web.entity.ResponseResult;
import com.nervenets.web.hibernate.dao.StatisticsOfOrderDao;
import com.nervenets.web.hibernate.dao.StatisticsOfUserDao;
import com.nervenets.web.hibernate.domain.statistics.StatisticsOfOrder;
import com.nervenets.web.hibernate.domain.statistics.StatisticsOfUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import javax.validation.ConstraintViolation;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Api(value = "统计类接口v1", description = "统计类相关接口")
@RestController
@RequestMapping("/api/v1/statistics")
public class StatisticsController extends BaseController {
    @Resource
    private StatisticsOfUserDao statisticsOfUserDao;
    @Resource
    private StatisticsOfOrderDao statisticsOfOrderDao;

    @ApiOperation("用户概况统计")
    @PostMapping("/user")
    public ResponseResult user(@RequestBody StatisticsTimeRangeParams params) {
        final Set<ConstraintViolation<StatisticsTimeRangeParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }

        final int startOfYesterday = JodaUtils.getStartOfYesterday();

        Specification<StatisticsOfUser> specification = (Specification<StatisticsOfUser>) (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            int startTime = params.getStartTime();
            int endTime = params.getEndTime();
            if (!(startTime > 0 && endTime > 0 && endTime > startTime)) {
                endTime = JodaUtils.getStartOfToday();
                startTime = endTime - 0x278d00;
            }
            predicates.add(criteriaBuilder.between(root.get("createTime"), startTime, endTime));
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        return successMessage(new StatisticsOfUserModel<>(
                statisticsOfUserDao.findByCreateTime(0),
                statisticsOfUserDao.findByCreateTime(startOfYesterday),
                statisticsOfUserDao.findAll(specification, new Sort(Sort.Direction.ASC, "id"))
        ));
    }

    @ApiOperation("服务订单概况统计")
    @PostMapping("/order")
    public ResponseResult order(@RequestBody StatisticsTimeRangeParams params) {
        final Set<ConstraintViolation<StatisticsTimeRangeParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }

        final int startOfYesterday = JodaUtils.getStartOfYesterday();

        Specification<StatisticsOfOrder> specification = (Specification<StatisticsOfOrder>) (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            int startTime = params.getStartTime();
            int endTime = params.getEndTime();
            if (!(startTime > 0 && endTime > 0 && endTime > startTime)) {
                endTime = JodaUtils.getStartOfToday();
                startTime = endTime - 0x278d00;
            }
            predicates.add(criteriaBuilder.between(root.get("createTime"), startTime, endTime));
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        return successMessage(new StatisticsOfUserModel<>(
                statisticsOfOrderDao.findByCreateTime(0),
                statisticsOfOrderDao.findByCreateTime(startOfYesterday),
                statisticsOfOrderDao.findAll(specification, new Sort(Sort.Direction.ASC, "id"))
        ));
    }

}
